#ifndef RT_VETOR
#define RT_VETOR

#include "matrix3d.h"

class Vector {
	public:
	double x;
	double y;
	double z;

	Vector(void);
	Vector (double x, double y, double z);
	Vector (Vector *b);
	~Vector();

	//calcula o produto interno do vetor atual
	double produtoInterno (Vector *b);
	//retorna o modulo do vetor atual ( ou norma )
	double modulo ();
	//retorna o vetor unitario do vetor atual
	Vector* vetorUnitario ();
	Vector* raioRefletido(Vector *normal);
	void set(double x, double y, double z);
	
	// retorna a coordenada do vetor pelo indice passado ( 0 -> x; 1->y; 2->z)
	double getCoord(int index);
	// seta uma coordenada do vetor pelo indice passado ( 0 -> x; 1->y; 2->z)
	void setCoord(double coord, int index);

	Vector* mudaBase(Vector *vetor);

	/**
	*   Projeta um vetor do R3 em outro, e retorna o vetor resultante.
	*/
	Vector* projecao(Vector *ontoVector );

	/**
	*   Combina��o linear de N vetores.
	*
	*   O primeiro par�metro indica N, o n�mero de vetores sendo combinados. Os par�metros
	*   seguintes s�o sempre pares [real scalar, Vector vector]. O vetor resultante � a
	*   soma de todos os vetores (scalar * vector) fornecidos, e normalizado (w = 1).
	*
	*   Exemplo: para obter o vetor 2 * v1 + 4 * v2 + 8 * v3, use:
	*      vector = algLinComb( 3, 2.0, v1, 4.0, v2, 8.0, v3 );
	*
	*   @warning Sempre passe os escalares como real explicitamente (1.0 ao inv�s de 1).
	*/
	Vector* combinacaoLinear(Vector *vetor );
	/**
	* Faz a combinacao linear do vetor atual com o vetor (vetor) passado 
	* os coeficientes a serem usados na combinacao são passados na forma de vetor (a) e (b)
	* (a) contem os coeficientes do vetor atual na combinacao linear e ser feita 
	* (b) contem os coeficientes do vetor (vetor) na combinacao linear a ser feita
	*/
	Vector* combinacaoLinear(Vector *vetor, Vector *a, Vector *b);
    /**
* o produto escalar de dois vetores e o mesmo que o produto interno 
* questao de nomeacao 
* o produto por um escalar esta implementado em multiplicacao()
*/
	//retorna o produto escalar
	double produtoEscalar(Vector *b);
	
	/**
	*   Produto vetorial entre dois vetores do R3 (ignorando a componente w).
	*/
	Vector* produtoVetorial(Vector *v2 );

	/**
	* calcula o angulo entre o vetor atual e o passado 
	**/
	double calculaAngulo(Vector *b);

	/**
	* diz se os vetores sao ortogonais, o atual e o passado 
	*/
	bool ortogonal(Vector *v);
	/**
	* diz se os vetores sao linearmente independentes ( o atual e o passado )
	* se nao sao linearmente independentes , entao um e uma combinacao linear do outro 
	* @return true, se sao linearmente independentes, false do contrario 
	*/
	bool linearmenteIndependente(Vector *v);
	/**
	* testa se os tres vetores sao linearmente independentes 
	* @return true, se sao linearmente independentes, false do contrario
	*/
	static bool linearmenteIndependente(Vector *v1, Vector *v2, Vector *v3); 

	/**
	* Retorna a Matrix de mudança de base vetorial 
	*/
	static Matrix3D* matrixMudancaBase(Matrix3D *baseOrigem, Matrix3D *baseDestino);

	//retorna uma soma entre o vetor atual i o passado
	Vector* soma(Vector *b);
	// retorna a subtracao entre o vetor atual e o passado 
	Vector* subtracao(Vector *b);	
	// retorna o produto por um escalar (multiplicacao por um escalar)
	Vector* multiplicacao(double escalar); 
	/**
	* multiplicacao de uma matrix3d por um vetor
	*
	*/
	Vector* multiplicacao(Matrix3D *m);

	void print();

	// monta a matrix de rotacao em torno do vetor v
	static Matrix3D* rotacao( Vector *u,double a );
	
};

#include "vector.cpp"

#endif
